"use client"; import { useAutoAnimate } from "@formkit/auto-animate/react"; import type { UseFormReturn } from "react-hook-form"; import { Controller, useFieldArray, useWatch } from "react-hook-form"; import { Toaster } from "sonner"; import { v4 as uuidv4 } from "uuid"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import classNames from "@calcom/ui/classNames"; import { Button } from "@calcom/ui/components/button"; import { FormCard } from "@calcom/ui/components/card"; import { BooleanToggleGroupField, Label, SelectField, TextField, MultiOptionInput, } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { Tooltip } from "@calcom/ui/components/tooltip"; import type { inferSSRProps } from "@lib/types/inferSSRProps"; import SingleForm from "../../components/SingleForm"; import type { getServerSidePropsForSingleFormView as getServerSideProps } from "../../components/getServerSidePropsSingleForm"; import { FieldTypes } from "../../lib/FieldTypes"; import type { RoutingFormWithResponseCount } from "../../types/types"; type HookForm = UseFormReturn; function Field({ fieldIndex, hookForm, hookFieldNamespace, deleteField, moveUp, moveDown, appUrl, disableTypeChange, }: { fieldIndex: number; hookForm: HookForm; hookFieldNamespace: `fields.${number}`; deleteField: { check: () => boolean; fn: () => void; }; moveUp: { check: () => boolean; fn: () => void; }; moveDown: { check: () => boolean; fn: () => void; }; appUrl: string; disableTypeChange: boolean; }) { const { t } = useLocale(); const router = hookForm.getValues(`${hookFieldNamespace}.router`); const routerField = hookForm.getValues(`${hookFieldNamespace}.routerField`); const label = useWatch({ control: hookForm.control, name: `${hookFieldNamespace}.label`, }); const identifier = useWatch({ control: hookForm.control, name: `${hookFieldNamespace}.identifier`, }); const fieldType = useWatch({ control: hookForm.control, name: `${hookFieldNamespace}.type`, }); const preCountFieldLabel = label || routerField?.label || "Field"; const fieldLabel = `${fieldIndex + 1}. ${preCountFieldLabel}`; return (
{ hookForm.setValue(`${hookFieldNamespace}.label`, e.target.value, { shouldDirty: true }); }} />
{ hookForm.setValue(`${hookFieldNamespace}.identifier`, e.target.value, { shouldDirty: true }); }} />
{ const defaultValue = FieldTypes.find((fieldType) => fieldType.value === value); if (disableTypeChange) { return (
); } else { return ( ({ ...baseStyles, fontSize: "14px", }), option: (baseStyles) => ({ ...baseStyles, fontSize: "14px", }), }} label="Type" isDisabled={!!router} containerClassName="data-testid-field-type" options={FieldTypes} onChange={(option) => { if (!option) { return; } onChange(option.value); }} defaultValue={defaultValue} /> ); } }} />
{["select", "multiselect"].includes(fieldType) ? (
500"]} defaultNumberOfOptions={4} pasteDelimiters={["\n", ","]} showMoveButtons={true} minOptions={1} addOptionLabel={t("add_an_option")} addOptionButtonColor="minimal" />
) : null}
{ return ( ); }} />
); } const FormEdit = ({ hookForm, form, appUrl, }: { hookForm: HookForm; form: inferSSRProps["form"]; appUrl: string; }) => { const fieldsNamespace = "fields"; const { fields: hookFormFields, append: appendHookFormField, remove: removeHookFormField, swap: swapHookFormField, // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore https://github.com/react-hook-form/react-hook-form/issues/6679 } = useFieldArray({ control: hookForm.control, name: fieldsNamespace, keyName: "_id", }); const [animationRef] = useAutoAnimate(); const addField = () => { appendHookFormField({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore id: uuidv4(), // This is same type from react-awesome-query-builder type: "text", label: "", }); }; // hookForm.reset(form); if (!form.fields) { form.fields = []; } return hookFormFields.length ? (
{hookFormFields.map((field, key) => { const existingField = Boolean((form.fields || []).find((f) => f.id === field.id)); const hasFormResponses = (form._count?.responses ?? 0) > 0; return ( hookFormFields.length > 1, fn: () => { removeHookFormField(key); }, }} moveUp={{ check: () => key !== 0, fn: () => { swapHookFormField(key, key - 1); }, }} moveDown={{ check: () => key !== hookFormFields.length - 1, fn: () => { if (key === hookFormFields.length - 1) { return; } swapHookFormField(key, key + 1); }, }} key={field.id} /> ); })}
{hookFormFields.length ? (
) : null}
) : (
{/* TODO: remake empty screen for V3 */}
{/* Icon card - Top */}
{/* Left fanned card */}
{/* Right fanned card */}

Create your first question

Fields are the form fields that the booker would see.

); }; export default function FormEditPage({ appUrl, permissions, ...props }: inferSSRProps & { appUrl: string }) { return ( <> } /> ); }